package cn.ddiancan.xddcloud.psc.flow.entity;

import java.util.Date;

import cn.ddiancan.xddcloud.psc.flow.utils.Assert;
import cn.ddiancan.xddcloud.psc.flow.utils.DateUtils;
import cn.ddiancan.xddcloud.psc.flow.enums.TaskState;
import cn.ddiancan.xddcloud.psc.flow.enums.TaskType;
import cn.ddiancan.xddcloud.psc.flow.engine.model.NodeModel;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * 历史任务实体类
 * @since 1.0
 */
@Getter
@Setter
@ToString
public class XddHisTask extends XddTask {

    /**
     * 调用外部流程定义ID
     */
    protected Long callProcessId;

    /**
     * 调用外部流程实例ID
     */
    protected Long callInstanceId;

    /**
     * 完成时间
     */
    protected Date finishTime;

    /**
     * 任务状态 0，活动 1，跳转 2，完成 3，拒绝 4，撤销审批  5，超时 6，终止 7，驳回终止
     */
    protected Integer taskState;

    /**
     * 处理耗时
     */
    protected Long duration;

    public XddHisTask setTaskState(TaskState taskState) {
        this.taskState = taskState.getValue();
        return this;
    }

    public XddHisTask setTaskState(Integer taskState) {
        Assert.isNull(TaskState.get(taskState), "插入的实例状态异常 [taskState=" + taskState + "]");
        this.taskState = taskState;
        return this;
    }

    public static XddHisTask of(XddTask flwTask, TaskState taskState) {
        return of(flwTask).setTaskState(taskState);
    }

    public static XddHisTask of(XddTask flwTask) {
        XddHisTask hisTask = new XddHisTask();
        hisTask.id = flwTask.getId();
        hisTask.tenantId = flwTask.getTenantId();
        hisTask.createName = flwTask.getCreateName();
        hisTask.createBy = flwTask.getCreateBy();
        hisTask.createTime = flwTask.getCreateTime();
        hisTask.instanceId = flwTask.getInstanceId();
        hisTask.parentTaskId = flwTask.getParentTaskId();
        hisTask.taskName = flwTask.getTaskName();
        hisTask.taskKey = flwTask.getTaskKey();
        hisTask.taskType = flwTask.getTaskType();
        hisTask.performType = flwTask.getPerformType();
        hisTask.actionUrl = flwTask.getActionUrl();
        hisTask.variable = flwTask.getVariable();
        hisTask.assignorId = flwTask.getAssignorId();
        hisTask.assignor = flwTask.getAssignor();
        hisTask.expireTime = flwTask.getExpireTime();
        hisTask.remindTime = flwTask.getRemindTime();
        hisTask.remindRepeat = flwTask.getRemindRepeat();
        hisTask.viewed = flwTask.getViewed();
        return hisTask;
    }

    public static XddHisTask ofCallInstance(NodeModel nodeModel, XddInstance instance) {
        XddHisTask flwHisTask = new XddHisTask();
        flwHisTask.setTenantId(instance.getTenantId());
        flwHisTask.setCreateName(instance.getCreateName());
        flwHisTask.setCreateBy(instance.getCreateBy());
        flwHisTask.setCreateTime(instance.getCreateTime());
        flwHisTask.setInstanceId(instance.getParentInstanceId());
        flwHisTask.setTaskName(nodeModel.getNodeName());
        flwHisTask.setTaskKey(nodeModel.getNodeKey());
        flwHisTask.setCallProcessId(instance.getProcessId());
        flwHisTask.setCallInstanceId(instance.getId());
        flwHisTask.setTaskType(nodeModel.getType());
        return flwHisTask;
    }

    /**
     * 根据历史任务产生撤回的任务对象
     * 创建人信息保留
     *
     * @return 任务对象
     */
    public XddTask undoTask(TaskType taskType) {
        XddTask flwTask = this.cloneTask(this.createName, this.createBy);
        flwTask.setTaskType(taskType);
        return flwTask;
    }

    /**
     * 计算流程实例处理耗时
     */
    public void calculateDuration() {
        this.finishTime = DateUtils.getCurrentDate();
        this.duration = DateUtils.calculateDateDifference(this.createTime, this.finishTime);
    }
}
